package org.example.seckill.service;

import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.example.seckill.dao.pojo.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
public class SeckillService {

//    /**
//     * 测试时使用
//     * @param args
//     */
//    public static void main(String[] args) {
//        SeckillService seckillService = new SeckillService();
//        seckillService.makeSeckill();
//    }

    @Autowired
    private DefaultMQProducer producer;

    /**
     * 模拟批量
     */
    public void makeSeckill(int aInventory) {
        String redisKey = "inventory";

        ExecutorService executorService = Executors.newFixedThreadPool(20);
        // 初始化库存
        try {
            Jedis jedis = new Jedis("127.0.0.1", 6379);
            jedis.set(redisKey, "1");
            jedis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 模拟批量访问（2000用户）进行秒杀
        for (int i = 1; i < 2000; i++) {
            final int userId = i;
            executorService.execute(() -> {
                Jedis jedis1 = new Jedis("127.0.0.1", 6379);
                try {
                    jedis1.watch(redisKey);
                    String inventoryStr = jedis1.get(redisKey);
                    int inventoryInt = Integer.valueOf(inventoryStr);

                    if (inventoryInt < 1 + aInventory) {
                        Transaction tx = jedis1.multi();
                        tx.incr(redisKey);
                        List list = tx.exec();
                        // 秒杀成功
                        if (list != null && list.size() > 0) {
                            System.out.println("第" + inventoryInt + "个商品已经被秒" + userId);

                            // 发送消息到`RocketMQ`
                            sendCreateOrderMsg(userId + ":" + inventoryInt);
                        }
                        // 被别人抢了
                        else {
                            System.out.println(userId + "没有秒到");
                        }
                    }
                    // 已被秒完
                    else {
//                        System.out.println("秒杀活动结束");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    jedis1.close();
                }
            });
        }
    }

    /**
     * 发送消息到RocketMQ
     */
    public void sendCreateOrderMsg(String msg) throws MQClientException, RemotingException, InterruptedException, MQBrokerException {
//        producer.start();

        Message message = new Message();
        message.setTopic("tp_seckill_order_01");
        message.setTags("create_order");
        message.setBody(msg.getBytes());

        SendResult sendResult = producer.send(message);
        System.out.println(sendResult.getSendStatus());
//        producer.shutdown();
    }

    /**
     * 发送延迟消息到RocketMQ
     */
    public void sendExpireOrderMsg(Order order) throws MQClientException, RemotingException, InterruptedException, MQBrokerException {
//        producer.start();

        Message message = new Message();
        message.setTopic("tp_seckill_order_01");
        message.setTags("expire_order");
        message.setBody(String.valueOf(order.getId()).getBytes());
        message.setDelayTimeLevel(2); // 延迟10秒

        SendResult sendResult = producer.send(message);
        System.out.println(sendResult.getSendStatus());
//        producer.shutdown();
    }
}
